from fastapi import APIRouter, Body, Depends, HTTPException, status
from app.crud.user import update_expectation
from app.dependencies import get_current_user, require_role
from app.models.job import Job, ParticipateJob
from app.schemas.job import AuditInDB
from app.schemas.user import ExpectationInDB, ExpectationUpdate, JobBase, JobUpdate, JobInDB, UserInDB, UserOccupied
from app.crud.job import create_job, get_job_participants, update_job, update_participant_audit
from app.models.user import User, UserRole
from fastapi.security import OAuth2PasswordBearer


router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

@router.put(
    "/expectations",
    summary="修改求职期望"
)
async def update_user_expectation(
    expectation: ExpectationUpdate,
    current_user: UserOccupied = Depends(get_current_user),
    _=Depends(require_role([UserRole.JOB_SEEKER]))
):
    """
    修改用户的求职期望信息
    
    权限要求:
    - 需要求职者权限
    
    参数:
    - expectation: ExpectationUpdate, 更新的求职期望信息
    - current_user: UserOccupied, 当前登录用户信息
    
    返回:
    - ExpectationInDB: 更新后的求职期望信息
    
    异常:
    - 400 Bad Request: 如果期望薪资为负数时抛出
    - 404 Not Found: 如果用户或期望不存在时抛出
    - 500 Internal Server Error: 如果更新失败时抛出
    """
    try:
        # 调用CRUD层方法更新期望
        updated_expectation = await update_expectation(current_user.id, expectation)
        return ExpectationInDB.model_validate(updated_expectation.__dict__)
    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新求职期望失败: {str(e)}"
        )
    
@router.post("/",summary="创建岗位信息")
async def create_new_job(
    job_data: JobBase,
    current_user: UserOccupied = Depends(get_current_user),
    _=Depends(require_role([UserRole.RECRUITER]))
):
    """
    创建新的工作职位
    
    参数:
    - job_data: JobBase, 包含工作职位信息的请求体，包括职位名称、公司信息、薪资等
    - current_user: UserOccupied, 当前认证用户，必须是招聘者角色
    
    返回:
    - JobInDB: 创建成功的工作职位详细信息，包含自动生成的ID和时间戳
    
    异常:
    - 400 Bad Request: 如果输入数据验证失败（如邮箱格式不正确等）
    - 403 Forbidden: 如果当前用户没有招聘者权限
    - 500 Internal Server Error: 如果服务器端创建工作职位时出错

    权限：
    - 需要认证
    - 仅限招聘者(RECRUITER)角色
    """
    job_dict = job_data.model_dump()
    job_dict["creator_id"] = current_user.id
    job_dict["avatar"] = None  # 设置默认头像为None
    
    if not job_dict.get("detail") or not job_dict["detail"].strip():
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="职位描述不能为空"
        )
        
    try:
        job_update = JobUpdate(**job_dict)
        job = await create_job(job_update)
        job_dict = job.__dict__
        job_dict["avatar"] = None  # 确保avatar字段存在
        return JobInDB.model_validate(job_dict)
    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"创建工作失败: {str(e)}"
        )


@router.put("/{job_id}",summary="修改岗位信息")
async def update_existing_job(
    job_id: int,
    job_data: JobBase,
    current_user: UserOccupied = Depends(get_current_user),
    _=Depends(require_role([UserRole.RECRUITER]))
):
    """
    更新现有的工作职位信息
    
    参数:
    - job_id: int, 要更新的工作ID
    - job_data: JobBase, 包含更新后的工作信息
    - current_user: UserOccupied, 当前认证用户，必须是招聘者角色
    
    返回:
    - JobInDB: 更新后的工作职位详细信息
    
    异常:
    - 400 Bad Request: 如果输入数据验证失败
    - 403 Forbidden: 如果当前用户没有权限
    - 404 Not Found: 如果工作不存在
    - 500 Internal Server Error: 如果服务器端更新失败

    权限：
    - 需要认证
    - 仅限招聘者(RECRUITER)角色
    - 只能修改自己创建的工作
    """
    try:
        job = await Job.get_or_none(job_id=job_id)
        if not job:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="工作不存在"
            )
        if job.creator_id != current_user.id:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="无权修改其他用户创建的工作"
            )
        job = await update_job(job_id, job_data)
        return JobInDB.model_validate(job.__dict__)
    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新工作失败: {str(e)}"
        )


@router.get("/", summary="获取岗位列表", response_model=list[JobInDB])
async def get_job_list(
    current_user: UserOccupied = Depends(get_current_user),
):
    """
    获取所有岗位列表
    
    参数:
    - current_user: UserOccupied, 当前认证用户
    
    返回:
    - list[JobInDB]: 岗位列表
    
    异常:
    - 500 Internal Server Error: 如果服务器端查询失败

    权限：
    - 需要认证
    - 所有角色均可访问
    """
    try:
        jobs = await Job.all().prefetch_related("creator")
        return [
            JobInDB(
                job_id=job.job_id,
                creator_id=job.creator_id,
                job_name=job.job_name,
                company=job.company,
                detail=job.detail,
                company_size=job.company_size,
                salary=float(job.salary),
                head=job.head,
                posts=job.posts,
                company_address=job.company_address,
                company_industry=job.company_industry,
                company_email=job.company_email,
                created_at=job.created_at,
                updated_at=job.updated_at,
                avatar=job.creator.avatar if job.creator else None
            )
            for job in jobs
        ]
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取岗位列表失败: {str(e)}"
        )

@router.post("/{job_id}/participate", summary="参与岗位", response_model=dict)
async def participate_job(
    job_id: int,
    current_user: UserOccupied = Depends(get_current_user),
     _=Depends(require_role([UserRole.JOB_SEEKER]))
):
    """
    求职者参与岗位
    
    参数:
    - job_id: int, 岗位ID
    - current_user: UserOccupied, 当前认证用户
    
    返回:
    - dict: 包含岗位信息和用户信息
    
    异常:
    - 404 Not Found: 如果岗位不存在
    - 400 Bad Request: 如果用户已参与该岗位
    - 500 Internal Server Error: 如果服务器端操作失败

    权限：
    - 需要认证
    - 仅限求职者角色
    """
    try:
        # 检查岗位是否存在
        job = await Job.get_or_none(job_id=job_id)
        if not job:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="岗位不存在"
            )
            
        # 检查是否已参与
        existing = await ParticipateJob.get_or_none(user_id=current_user.id, job_id=job_id)
        if existing:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="您已参与该岗位"
            )
            
        # 创建参与记录
        await ParticipateJob.create(user_id=current_user.id, job_id=job_id)
        
        # 获取用户详细信息
        user = await User.get(id=current_user.id)
        
        return {
            "job": JobInDB.model_validate(job.__dict__),
            "user": UserInDB.model_validate(user.__dict__)
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"参与岗位失败: {str(e)}"
        )


@router.get(
    "/{job_id}/participants",
    summary="获取参与岗位的用户信息"
)
async def get_job_participants_route(
    job_id: int,
    current_user: UserOccupied = Depends(get_current_user),
     _=Depends(require_role([UserRole.RECRUITER]))
):
    """
    获取参与指定岗位的用户信息
    
    权限要求:
    - 需要招聘者权限
    - 只能获取自己发布的岗位信息
    
    参数:
    - job_id: int, 岗位ID
    - current_user: UserOccupied, 当前登录用户信息
    
    返回:
    - list[ParticipateJob]: 参与该岗位的用户列表
    
    异常:
    - 404 Not Found: 如果岗位不存在时抛出
    - 403 Forbidden: 如果不是岗位创建者时抛出
    - 500 Internal Server Error: 如果查询失败时抛出
    """
    try:
        # 检查岗位是否存在且是否为当前用户创建
        job = await Job.get_or_none(job_id=job_id)
        if not job:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="岗位不存在"
            )
            
        if job.creator_id != current_user.id:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="无权查看该岗位的参与者信息"
            )
            
        # 获取参与者信息
        participants = await get_job_participants(job_id)
        return participants
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取参与者信息失败: {str(e)}"
        )


@router.put("/participants/{participant_id}/audit",
             response_model=AuditInDB,
              summary="审核求职者参与岗位"
              )
async def update_participant_audit_status(
    participant_id: int,
    audit_status: int = Body(..., embed=True, ge=1, le=3, description="审核状态(1:审核中 2:未通过 3:通过)"),
    current_user: UserOccupied = Depends(get_current_user),
    _=Depends(require_role([UserRole.RECRUITER]))
):
    """
    修改参与工作的审核状态
    
    权限要求:
    - 需要招聘者权限
    - 只能修改自己发布岗位的参与者状态
    
    参数:
    - participant_id: int, 参与记录ID
    - audit_status: int, 审核状态(1:审核中 2:未通过 3:通过)
    - current_user: UserOccupied, 当前登录用户信息
    
    返回:
    - AuditInDB: 更新后的审核记录
    
    异常:
    - 404 Not Found: 如果参与记录不存在时抛出
    - 403 Forbidden: 如果不是岗位创建者时抛出
    - 500 Internal Server Error: 如果更新失败时抛出
    """
    try:
        # 检查参与记录是否存在且是否为当前用户创建的岗位
        participant = await ParticipateJob.get_or_none(id=participant_id).prefetch_related('job')
        if not participant:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="参与记录不存在"
            )
            
        if participant.job.creator_id != current_user.id:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="无权修改该参与记录的审核状态"
            )
            
        # 更新审核状态
        return await update_participant_audit(participant_id, audit_status)
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新审核状态失败: {str(e)}"
        )


@router.delete("/{job_id}/participants", summary="删除当前用户与岗位的关联")
async def delete_job_participation(
    job_id: int,
    current_user: UserOccupied = Depends(get_current_user),
    _=Depends(require_role([UserRole.JOB_SEEKER]))
):
    """
    删除当前用户与指定岗位的关联
    
    权限要求:
    - 需要求职者权限
    - 只能删除自己的参与记录
    
    参数:
    - job_id: int, 岗位ID
    - current_user: UserOccupied, 当前登录用户信息
    
    返回:
    - dict: 包含成功消息
    
    异常:
    - 404 Not Found: 如果岗位或参与记录不存在时抛出
    - 403 Forbidden: 如果不是自己的参与记录时抛出
    - 500 Internal Server Error: 如果删除失败时抛出
    """
    try:
        # 检查岗位是否存在
        job = await Job.get_or_none(job_id=job_id)
        if not job:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="岗位不存在"
            )
            
        # 检查参与记录是否存在
        participant = await ParticipateJob.get_or_none(job_id=job_id, user_id=current_user.id)
        if not participant:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="您未参与该岗位"
            )
            
        # 删除参与记录
        await participant.delete()
        return {"message": "成功删除您与该岗位的关联"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"删除参与记录失败: {str(e)}"
        )
